home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************
- Written by:
- Fred Gansevles <Fred.Gansevles@cs.utwente.nl>
- Vakgroep Spa,
- Faculteit der Informatica,
- Universiteit Twente,
- Enschede,
- the Netherlands.
- ******************************************************************/
-
- /* NIS module implementation */
-
- #include "allobjects.h"
- #include "modsupport.h"
- #include "ceval.h"
-
- #include <sys/time.h>
- #include <sys/types.h>
- #include <rpc/rpc.h>
- #include <rpcsvc/yp_prot.h>
- #include <rpcsvc/ypclnt.h>
-
- static object *NisError;
-
- static object *
- nis_error (err)
- int err;
- {
- err_setstr(NisError, yperr_string(err));
- return NULL;
- }
-
- static struct nis_map {
- char *alias;
- char *map;
- } aliases [] = {
- {"passwd", "passwd.byname"},
- {"group", "group.byname"},
- {"networks", "networks.byaddr"},
- {"hosts", "hosts.byname"},
- {"protocols", "protocols.bynumber"},
- {"services", "services.byname"},
- {"aliases", "mail.aliases"},
- {"ethers", "ethers.byname"},
- {0L, 0L}
- };
-
- static char *
- nis_mapname (map)
- char *map;
- {
- int i;
-
- for (i=0; aliases[i].alias != 0L; i++)
- if (!strcmp (aliases[i].alias, map))
- map = aliases[i].map;
- return map;
- }
-
- typedef int (*foreachfunc) PROTO((int, char *, int, char *, int, char *));
-
- static int
- nis_foreach (instatus, inkey, inkeylen, inval, invallen, indata)
- int instatus;
- char *inkey;
- int inkeylen;
- char *inval;
- int invallen;
- object *indata;
- {
- if (instatus == YP_TRUE) {
- object *key = newsizedstringobject(inkey, inkeylen);
- object *val = newsizedstringobject(inval, invallen);
- int err;
- if (key == NULL || val == NULL) {
- /* XXX error -- don't know how to handle */
- err_clear();
- XDECREF(key);
- XDECREF(val);
- return 1;
- }
- err = mappinginsert(indata, key, val);
- DECREF(key);
- DECREF(val);
- if (err != 0) {
- err_clear();
- return 1;
- }
- return 0;
- }
- return 1;
- }
-
- static object *
- nis_match (self, args)
- object *self;
- object *args;
- {
- char *match;
- char *domain;
- int keylen, len;
- char *key, *map;
- int err;
- object *res;
-
- if (!getargs(args, "(s#s)", &key, &keylen, &map))
- return NULL;
- if ((err = yp_get_default_domain(&domain)) != 0)
- return nis_error(err);
- BGN_SAVE
- map = nis_mapname (map);
- err = yp_match (domain, map, key, keylen, &match, &len);
- END_SAVE
- if (err != 0)
- return nis_error(err);
- res = newsizedstringobject (match, len);
- free (match);
- return res;
- }
-
- static object *
- nis_cat (self, args)
- object *self;
- object *args;
- {
- char *domain;
- char *map;
- struct ypall_callback cb;
- object *cat;
- int err;
-
- if (!getstrarg(args, &map))
- return NULL;
- if ((err = yp_get_default_domain(&domain)) != 0)
- return nis_error(err);
- cat = newdictobject ();
- if (cat == NULL)
- return NULL;
- cb.foreach = (foreachfunc)nis_foreach;
- cb.data = (char *)cat;
- BGN_SAVE
- map = nis_mapname (map);
- err = yp_all (domain, map, &cb);
- END_SAVE
- if (err != 0) {
- DECREF(cat);
- return nis_error(err);
- }
- return cat;
- }
-
- /* These should be u_long on Sun h/w but not on 64-bit h/w.
- This is not portable to machines with 16-bit ints and no prototypes */
- #ifndef YPPROC_MAPLIST
- #define YPPROC_MAPLIST 11
- #endif
- #ifndef YPPROG
- #define YPPROG 100004
- #endif
- #ifndef YPVERS
- #define YPVERS 2
- #endif
-
- typedef char *domainname;
- typedef char *mapname;
-
- enum nisstat {
- NIS_TRUE = 1,
- NIS_NOMORE = 2,
- NIS_FALSE = 0,
- NIS_NOMAP = -1,
- NIS_NODOM = -2,
- NIS_NOKEY = -3,
- NIS_BADOP = -4,
- NIS_BADDB = -5,
- NIS_YPERR = -6,
- NIS_BADARGS = -7,
- NIS_VERS = -8
- };
- typedef enum nisstat nisstat;
-
- struct nismaplist {
- mapname map;
- struct nismaplist *next;
- };
- typedef struct nismaplist nismaplist;
-
- struct nisresp_maplist {
- nisstat stat;
- nismaplist *maps;
- };
- typedef struct nisresp_maplist nisresp_maplist;
-
- static struct timeval TIMEOUT = { 25, 0 };
-
- static
- bool_t
- nis_xdr_domainname(xdrs, objp)
- XDR *xdrs;
- domainname *objp;
- {
- if (!xdr_string(xdrs, objp, YPMAXDOMAIN)) {
- return (FALSE);
- }
- return (TRUE);
- }
-
- static
- bool_t
- nis_xdr_mapname(xdrs, objp)
- XDR *xdrs;
- mapname *objp;
- {
- if (!xdr_string(xdrs, objp, YPMAXMAP)) {
- return (FALSE);
- }
- return (TRUE);
- }
-
- static
- bool_t
- nis_xdr_ypmaplist(xdrs, objp)
- XDR *xdrs;
- nismaplist *objp;
- {
- if (!nis_xdr_mapname(xdrs, &objp->map)) {
- return (FALSE);
- }
- if (!xdr_pointer(xdrs, (char **)&objp->next, sizeof(nismaplist), nis_xdr_ypmaplist)) {
- return (FALSE);
- }
- return (TRUE);
- }
-
- static
- bool_t
- nis_xdr_ypstat(xdrs, objp)
- XDR *xdrs;
- nisstat *objp;
- {
- if (!xdr_enum(xdrs, (enum_t *)objp)) {
- return (FALSE);
- }
- return (TRUE);
- }
-
-
- static
- bool_t
- nis_xdr_ypresp_maplist(xdrs, objp)
- XDR *xdrs;
- nisresp_maplist *objp;
- {
- if (!nis_xdr_ypstat(xdrs, &objp->stat)) {
- return (FALSE);
- }
- if (!xdr_pointer(xdrs, (char **)&objp->maps, sizeof(nismaplist), nis_xdr_ypmaplist)) {
- return (FALSE);
- }
- return (TRUE);
- }
-
-
- static
- nisresp_maplist *
- nisproc_maplist_2(argp, clnt)
- domainname *argp;
- CLIENT *clnt;
- {
- static nisresp_maplist res;
-
- memset(&res, 0, sizeof(res));
- if (clnt_call(clnt, YPPROC_MAPLIST, nis_xdr_domainname, (caddr_t)argp,
- nis_xdr_ypresp_maplist, (caddr_t)&res, TIMEOUT)
- != RPC_SUCCESS) {
- return (NULL);
- }
- return (&res);
- }
-
- static
- nismaplist *
- nis_maplist ()
- {
- nisresp_maplist *list;
- char *dom;
- CLIENT *cl, *clnt_create();
- char *server;
-
- yp_get_default_domain (&dom);
- yp_master (dom, aliases[0].map, &server);
- cl = clnt_create(server, YPPROG, YPVERS, "tcp");
- if (cl == NULL) {
- clnt_pcreateerror(server);
- return NULL;
- }
- list = nisproc_maplist_2 (&dom, cl);
- if (list == NULL)
- return NULL;
- if (list->stat != NIS_TRUE)
- return NULL;
- return list->maps;
- }
-
- static object *
- nis_maps (self, args)
- object *self;
- object *args;
- {
- nismaplist *maps;
- object *list;
-
- if ((maps = nis_maplist ()) == NULL)
- return NULL;
- if ((list = newlistobject(0)) == NULL)
- return NULL;
- for (maps = maps->next; maps; maps = maps->next) {
- if (addlistitem (list, newstringobject (maps->map)) < 0) {
- DECREF(list);
- list = NULL;
- break;
- }
- }
- /* XXX Shouldn't we free the list of maps now? */
- return list;
- }
-
- static struct methodlist nis_methods[] = {
- {"match", nis_match},
- {"cat", nis_cat},
- {"maps", nis_maps},
- {NULL, NULL} /* Sentinel */
- };
-
- void
- initnis ()
- {
- object *m, *d;
- m = initmodule("nis", nis_methods);
- d = getmoduledict(m);
- NisError = newstringobject("nis.error");
- if (NisError == NULL || dictinsert(d, "error", NisError) != 0)
- fatal("Cannot define nis.error");
- }
-